<title>生产（正式）环境 分账</title>
<?php
function http_post_data($url, $data_string) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSLVERSION, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($data_string))
    );
    ob_start();
    curl_exec($ch);
    $return_content = ob_get_contents();
    //echo $return_content."<br>";
    ob_end_clean();
    $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    // return array($return_code, $return_content);
    return $return_content;
}

$transCodeArr=array(
	'a'=>array(
		'Name'=>'按金额',
		'Val'=>'202002',
	),
	'b'=>array(
		'Name'=>'按流水',
		'Val'=>'202001'
	)
);
$time=time();
$requestTimestamp=date('YmdHis', $time);
echo '当前时间：'.$requestTimestamp.'<br>';
$data = array(
    "groupId" => "000002",
    "verNo" => "100",
    "srcReqTime" => "144917",
    "payAmt" => "1",
    "transCode" => "202002",
    "channelId" => "043",
    "srcReqDate" => "20200415",
    "merNo" => "10000000013400",
    "srcReqId" => $requestTimestamp,
    "merOrderNo" => "CC002"
);

//测试资料-按流水
$data = array(
    "groupId" => "000004",
    "verNo" => "100",
    "srcReqTime" => "144917",
    "payAmt" => "1",
    "transCode" => "202001", //202002金额（余额有多少打多少）  202001流水（每笔划付分账需要对应原支付交易订单流水）
    "channelId" => "043",
    "srcReqDate" => "20200508",
    "merNo" => "10000000014000",
    "srcReqId" => $requestTimestamp,
    "merOrderNo" => "AAAA0001"
);

//测试资料-按金额划付
$data = array(
    "groupId" => "151515",
    "merNo" => "10000000016327",
    "verNo" => "100",
    "srcReqTime" => "144917",
    "payAmt" => "1",
    "transCode" => "202002",   //202002金额（余额有多少打多少）  202001流水（每笔划付分账需要对应原支付交易订单流水）
    "channelId" => "043",
    "srcReqDate" => "20200508",
    "srcReqId" => $requestTimestamp,
    "merOrderNo" => "AAAA0003"
);

//测试资料-按金额分账
$data = array(
    "groupId" => "151515",
    "merNo" => "10000000016327",
    "verNo" => "100",
    "srcReqTime" => "144917",
    "payAmt" => "1",
    "transCode" => "202004",   //202002金额（余额有多少打多少）  202001流水（每笔划付分账需要对应原支付交易订单流水）
    "channelId" => "043",
    "srcReqDate" => "20200508",
    "srcReqId" => $requestTimestamp,
	"payType"=>"0",
    "cardNo" => hash("sha256","6236681300001758484"),
	"ps"=>"123"
);
$url = "https://mobl-test.chinaums.com/channel/Business/UnifyMulti/202004";


//正式资料-按金额分账
$data = array(
    "groupId" => "SZSJCB",
    "merNo" => "10001004439606",
    "verNo" => "100",
    "srcReqTime" => "144917",
    "payAmt" => "1",
    "transCode" => "202004",    //按金额分账
    "channelId" => "043",
    "srcReqDate" => "20200509",
    "srcReqId" => $requestTimestamp,
	"payType"=>"0",
	"cardNo"=>hash("sha256","6222600730002607992"),
	"ps"=>"123"	
 );
$url = "https://mobl-test.chinaums.com/channel/Business/UnifyMulti/202004";
 
 
$param = getParamsString($data);
$param=rtrim($param, '&');
$sign = sign($param);
//var_dump($param);
//echo '<br/>sign='.$sign.'<br/>';
/*var_dump($param);
echo '<br/>sign='.$sign;exit;*/
$data['signature'] = $sign;
$aaa = http_post_data($url, json_encode($data));
echo hash("sha256","I am a happy boy.");

echo '<pre>';
echo 'transCode：'.$data['transCode'];
echo '<br><br>提交报文：<br>';
echo indent(json_encode($data,true));
echo '<br><br>返回报文：<br>';
echo indent($aaa);

exit;


function indent($json) {

    $result = '';

    $pos = 0;

    $strLen = strlen($json);

    $indentStr = '';

    $newLine = "\n";

    $prevChar = '';

    $outOfQuotes = true;

    for ($i = 0; $i <= $strLen; $i++) {

        // Grab the next character in the string.

        $char = substr($json, $i, 1);

        // Are we inside a quoted string?

        if ($char == '"' && $prevChar != '\\') {

            $outOfQuotes = !$outOfQuotes;

            // If this character is the end of an element,

            // output a new line and indent the next line.

             

        } else if (($char == '}' || $char == ']') && $outOfQuotes) {

            $result.= $newLine;

            $pos--;

            for ($j = 0; $j < $pos; $j++) {

                $result.= $indentStr;

            }

        }

        // Add the character to the result string.

        $result.= $char;

        // If the last character was the beginning of an element,

        // output a new line and indent the next line.

        if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) {

            $result.= $newLine;

            if ($char == '{' || $char == '[') {

                $pos++;

            }

            for ($j = 0; $j < $pos; $j++) {

                $result.= $indentStr;

            }

        }

        $prevChar = $char;

    }

    return $result;

}



/**
 * 生成签名前的字符串
 *
 * @param $params
 * @return string
 */
function getParamsString($params)
{
    if (!is_array($params))
        $params = array();
    ksort($params);
    reset($params);
    $str = '';
    foreach ($params as $k => $v) {
        $str .= $v != '' ? $k.'='.$v.'&':'';
    }
    return $str;
}
/**
 * 根据原文生成签名内容
 *
 * @param string $data 原文内容
 *
 * @return string
 */
function sign($data)
{
    $filePath = 'rsa_private_dev.pfx';
    if(!file_exists($filePath)) {
        return false;
    }
    $pkcs12 = file_get_contents($filePath);
    if (openssl_pkcs12_read($pkcs12, $certs, '123456')) {
        $privateKey = $certs['pkey']; //根据实际情况键值可能不同
        $binary_signature = "";
        if (openssl_sign(utf8_encode($data), $binarySignature, $privateKey, OPENSSL_ALGO_SHA256)) {
            return bin2hex($binarySignature);
        } else {
            return '';
        }
    } else {
        return '';
    }
}
/**
 * 验证签名自己生成的是否正确
 *
 * @param string $data 签名的原文
 * @param string $signature 签名
 *
 * @return bool
 */
function verifySign($data, $signature)
{
    $filePath = 'rsa_private_dev.pfx';
    if(!file_exists($filePath)) {
        return false;
    }

    $pkcs12 = file_get_contents($filePath);
    if (openssl_pkcs12_read($pkcs12, $certs, '123456')) {
        $publicKey = $certs['cert'];
        $ok = openssl_verify($data, hex2bin($signature), $publicKey);
        if ($ok == 1) {
            return true;
        }
    }
    return false;
}

/**
 * 验证返回的签名是否正确
 * @filePath 为cer文件路径
 * @param string $data 要验证的签名原文
 * @return bool
 */
function verifyRespondSign($data)
{
    $publicPath = 'rsa_public_dev.cer';
    if(!file_exists($publicPath)) {
        return false;
    }
    $sign = getSignContent($data);

    $signature = $data['signature'];
    $cert = file_get_contents($publicPath);
    $cert = '-----BEGIN CERTIFICATE-----' . PHP_EOL
        . chunk_split(base64_encode($cert), 64, PHP_EOL)
        . '-----END CERTIFICATE-----' . PHP_EOL;
    $pubKeyId = openssl_get_publickey($cert);
    $signature = hex2bin($signature);//把十六进制值转换为 ASCII 字符
    $ok = openssl_verify($sign, $signature, $pubKeyId,OPENSSL_ALGO_SHA256);

    if ($ok == 1) {
        openssl_free_key($pubKeyId);
        return true;
    }
    return false;
}